home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / compiler / mips / move.lisp < prev    next >
Encoding:
Text File  |  1991-11-09  |  9.5 KB  |  322 lines

  1. ;;; -*- Package: C; Log: C.Log -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: move.lisp,v 1.29 91/11/09 02:37:43 wlott Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. ;;; $Header: move.lisp,v 1.29 91/11/09 02:37:43 wlott Exp $
  15. ;;;
  16. ;;;    This file contains the MIPS VM definition of operand loading/saving and
  17. ;;; the Move VOP.
  18. ;;;
  19. ;;; Written by Rob MacLachlan.
  20. ;;; MIPS conversion by William Lott.
  21. ;;;
  22. (in-package "MIPS")
  23.  
  24.  
  25. (define-move-function (load-immediate 1) (vop x y)
  26.   ((null unsigned-immediate immediate zero negative-immediate
  27.      random-immediate immediate-base-char)
  28.    (any-reg descriptor-reg))
  29.   (let ((val (tn-value x)))
  30.     (etypecase val
  31.       (integer
  32.        (inst li y (fixnum val)))
  33.       (null
  34.        (move y null-tn))
  35.       (symbol
  36.        (load-symbol y val))
  37.       (character
  38.        (inst li y (logior (ash (char-code val) type-bits)
  39.               base-char-type))))))
  40.  
  41. (define-move-function (load-number 1) (vop x y)
  42.   ((unsigned-immediate immediate zero negative-immediate random-immediate)
  43.    (signed-reg unsigned-reg))
  44.   (inst li y (tn-value x)))
  45.  
  46. (define-move-function (load-base-char 1) (vop x y)
  47.   ((immediate-base-char) (base-char-reg))
  48.   (inst li y (char-code (tn-value x))))
  49.  
  50. (define-move-function (load-system-area-pointer 1) (vop x y)
  51.   ((immediate-sap) (sap-reg))
  52.   (inst li y (sap-int (tn-value x))))
  53.  
  54. (define-move-function (load-constant 5) (vop x y)
  55.   ((constant) (descriptor-reg))
  56.   (loadw y code-tn (tn-offset x) other-pointer-type))
  57.  
  58. (define-move-function (load-stack 5) (vop x y)
  59.   ((control-stack) (any-reg descriptor-reg))
  60.   (load-stack-tn y x))
  61.  
  62. (define-move-function (load-number-stack 5) (vop x y)
  63.   ((base-char-stack) (base-char-reg)
  64.    (sap-stack) (sap-reg)
  65.    (signed-stack) (signed-reg)
  66.    (unsigned-stack) (unsigned-reg))
  67.   (let ((nfp (current-nfp-tn vop)))
  68.     (loadw y nfp (tn-offset x))))
  69.  
  70. (define-move-function (store-stack 5) (vop x y)
  71.   ((any-reg descriptor-reg) (control-stack))
  72.   (store-stack-tn y x))
  73.  
  74. (define-move-function (store-number-stack 5) (vop x y)
  75.   ((base-char-reg) (base-char-stack)
  76.    (sap-reg) (sap-stack)
  77.    (signed-reg) (signed-stack)
  78.    (unsigned-reg) (unsigned-stack))
  79.   (let ((nfp (current-nfp-tn vop)))
  80.     (storew x nfp (tn-offset y))))
  81.  
  82.  
  83. ;;;; The Move VOP:
  84. ;;;
  85. (define-vop (move)
  86.   (:args (x :target y
  87.         :scs (any-reg descriptor-reg)
  88.         :load-if (not (location= x y))))
  89.   (:results (y :scs (any-reg descriptor-reg)
  90.            :load-if (not (location= x y))))
  91.   (:effects)
  92.   (:affected)
  93.   (:generator 0
  94.     (move y x)))
  95.  
  96. (define-move-vop move :move
  97.   (any-reg descriptor-reg)
  98.   (any-reg descriptor-reg))
  99.  
  100. ;;; Make Move the check VOP for T so that type check generation doesn't think
  101. ;;; it is a hairy type.  This also allows checking of a few of the values in a
  102. ;;; continuation to fall out.
  103. ;;;
  104. (primitive-type-vop move (:check) t)
  105.  
  106. ;;;    The Move-Argument VOP is used for moving descriptor values into another
  107. ;;; frame for argument or known value passing.
  108. ;;;
  109. (define-vop (move-argument)
  110.   (:args (x :target y
  111.         :scs (any-reg descriptor-reg))
  112.      (fp :scs (any-reg)
  113.          :load-if (not (sc-is y any-reg descriptor-reg))))
  114.   (:results (y))
  115.   (:generator 0
  116.     (sc-case y
  117.       ((any-reg descriptor-reg)
  118.        (move y x))
  119.       (control-stack
  120.        (storew x fp (tn-offset y))))))
  121. ;;;
  122. (define-move-vop move-argument :move-argument
  123.   (any-reg descriptor-reg)
  124.   (any-reg descriptor-reg))
  125.  
  126.  
  127.  
  128. ;;;; ILLEGAL-MOVE
  129.  
  130. ;;; This VOP exists just to begin the lifetime of a TN that couldn't be written
  131. ;;; legally due to a type error.  An error is signalled before this VOP is
  132. ;;; so we don't need to do anything (not that there would be anything sensible
  133. ;;; to do anyway.)
  134. ;;;
  135. (define-vop (illegal-move)
  136.   (:args (x) (type))
  137.   (:results (y))
  138.   (:ignore y)
  139.   (:vop-var vop)
  140.   (:save-p :compute-only)
  141.   (:generator 666
  142.     (error-call vop object-not-type-error x type)))
  143.  
  144.  
  145.  
  146. ;;;; Moves and coercions:
  147.  
  148. ;;; These MOVE-TO-WORD VOPs move a tagged integer to a raw full-word
  149. ;;; representation.  Similarly, the MOVE-FROM-WORD VOPs converts a raw integer
  150. ;;; to a tagged bignum or fixnum.
  151.  
  152. ;;; Arg is a fixnum, so just shift it.  We need a type restriction because some
  153. ;;; possible arg SCs (control-stack) overlap with possible bignum arg SCs.
  154. ;;;
  155. (define-vop (move-to-word/fixnum)
  156.   (:args (x :scs (any-reg descriptor-reg)))
  157.   (:results (y :scs (signed-reg unsigned-reg)))
  158.   (:arg-types tagged-num)
  159.   (:note "fixnum untagging")
  160.   (:generator 1
  161.     (inst sra y x 2)))
  162. ;;;
  163. (define-move-vop move-to-word/fixnum :move
  164.   (any-reg descriptor-reg) (signed-reg unsigned-reg))
  165.  
  166. ;;; Arg is a non-immediate constant, load it.
  167. (define-vop (move-to-word-c)
  168.   (:args (x :scs (constant)))
  169.   (:results (y :scs (signed-reg unsigned-reg)))
  170.   (:note "constant load")
  171.   (:generator 1
  172.     (inst li y (tn-value x))))
  173. ;;;
  174. (define-move-vop move-to-word-c :move
  175.   (constant) (signed-reg unsigned-reg))
  176.  
  177. ;;; Arg is a fixnum or bignum, figure out which and load if necessary.
  178. (define-vop (move-to-word/integer)
  179.   (:args (x :scs (descriptor-reg)))
  180.   (:results (y :scs (signed-reg unsigned-reg)))
  181.   (:note "integer to untagged word coercion")
  182.   (:temporary (:scs (non-descriptor-reg)) temp)
  183.   (:generator 3
  184.     (let ((done (gen-label)))
  185.       (inst and temp x 3)
  186.       (inst beq temp done)
  187.       (inst sra y x 2)
  188.  
  189.       (loadw y x vm:bignum-digits-offset vm:other-pointer-type)
  190.       (emit-label done))))
  191. ;;;
  192. (define-move-vop move-to-word/integer :move
  193.   (descriptor-reg) (signed-reg unsigned-reg))
  194.  
  195.  
  196. ;;; Result is a fixnum, so we can just shift.  We need the result type
  197. ;;; restriction because of the control-stack ambiguity noted above.
  198. ;;;
  199. (define-vop (move-from-word/fixnum)
  200.   (:args (x :scs (signed-reg unsigned-reg)))
  201.   (:results (y :scs (any-reg descriptor-reg)))
  202.   (:result-types tagged-num)
  203.   (:note "fixnum tagging")
  204.   (:generator 1
  205.     (inst sll y x 2)))
  206. ;;;
  207. (define-move-vop move-from-word/fixnum :move
  208.   (signed-reg unsigned-reg) (any-reg descriptor-reg))
  209.  
  210. ;;; Result may be a bignum, so we have to check.  Use a worst-case cost to make
  211. ;;; sure people know they may be number consing.
  212. ;;;
  213. (define-vop (move-from-signed)
  214.   (:args (arg :scs (signed-reg unsigned-reg) :target x))
  215.   (:results (y :scs (any-reg descriptor-reg)))
  216.   (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) x temp)
  217.   (:note "signed word to integer coercion")
  218.   (:generator 18
  219.     (move x arg)
  220.     (let ((fixnum (gen-label))
  221.       (done (gen-label)))
  222.       (inst sra temp x 29)
  223.       (inst beq temp fixnum)
  224.       (inst nor temp zero-tn)
  225.       (inst beq temp done)
  226.       (inst sll y x 2)
  227.       
  228.       (pseudo-atomic (temp)
  229.     (inst addu y alloc-tn vm:other-pointer-type)
  230.     (inst addu alloc-tn
  231.           (vm:pad-data-block (1+ vm:bignum-digits-offset)))
  232.     (inst li temp (logior (ash 1 vm:type-bits) vm:bignum-type))
  233.     (storew temp y 0 vm:other-pointer-type)
  234.     (storew x y vm:bignum-digits-offset vm:other-pointer-type))
  235.       (inst b done)
  236.       (inst nop)
  237.       
  238.       (emit-label fixnum)
  239.       (inst sll y x 2)
  240.       (emit-label done))))
  241. ;;;
  242. (define-move-vop move-from-signed :move
  243.   (signed-reg) (descriptor-reg))
  244.  
  245.  
  246. ;;; Check for fixnum, and possibly allocate one or two word bignum result.  Use
  247. ;;; a worst-case cost to make sure people know they may be number consing.
  248. ;;;
  249. (define-vop (move-from-unsigned)
  250.   (:args (arg :scs (signed-reg unsigned-reg) :target x))
  251.   (:results (y :scs (any-reg descriptor-reg)))
  252.   (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) x temp)
  253.   (:note "unsigned word to integer coercion")
  254.   (:generator 20
  255.     (move x arg)
  256.     (let ((done (gen-label))
  257.       (one-word (gen-label)))
  258.       (inst sra temp x 29)
  259.       (inst beq temp done)
  260.       (inst sll y x 2)
  261.       
  262.       (pseudo-atomic (temp)
  263.     (inst addu y alloc-tn vm:other-pointer-type)
  264.     (inst addu alloc-tn
  265.           (vm:pad-data-block (1+ vm:bignum-digits-offset)))
  266.     (inst bgez x one-word)
  267.     (inst li temp (logior (ash 1 vm:type-bits) vm:bignum-type))
  268.     (inst addu alloc-tn (vm:pad-data-block 1))
  269.     (inst li temp (logior (ash 2 vm:type-bits) vm:bignum-type))
  270.     (emit-label one-word)
  271.     (storew temp y 0 vm:other-pointer-type)
  272.     (storew x y vm:bignum-digits-offset vm:other-pointer-type))
  273.       (emit-label done))))
  274. ;;;
  275. (define-move-vop move-from-unsigned :move
  276.   (unsigned-reg) (descriptor-reg))
  277.  
  278.  
  279. ;;; Move untagged numbers.
  280. ;;;
  281. (define-vop (word-move)
  282.   (:args (x :target y
  283.         :scs (signed-reg unsigned-reg)
  284.         :load-if (not (location= x y))))
  285.   (:results (y :scs (signed-reg unsigned-reg)
  286.            :load-if (not (location= x y))))
  287.   (:effects)
  288.   (:affected)
  289.   (:note "word integer move")
  290.   (:generator 0
  291.     (move y x)))
  292. ;;;
  293. (define-move-vop word-move :move
  294.   (signed-reg unsigned-reg) (signed-reg unsigned-reg))
  295.  
  296.  
  297. ;;; Move untagged number arguments/return-values.
  298. ;;;
  299. (define-vop (move-word-argument)
  300.   (:args (x :target y
  301.         :scs (signed-reg unsigned-reg))
  302.      (fp :scs (any-reg)
  303.          :load-if (not (sc-is y sap-reg))))
  304.   (:results (y))
  305.   (:note "word integer argument move")
  306.   (:generator 0
  307.     (sc-case y
  308.       ((signed-reg unsigned-reg)
  309.        (move y x))
  310.       ((signed-stack unsigned-stack)
  311.        (storew x fp (tn-offset y))))))
  312. ;;;
  313. (define-move-vop move-word-argument :move-argument
  314.   (descriptor-reg any-reg signed-reg unsigned-reg) (signed-reg unsigned-reg))
  315.  
  316.  
  317. ;;; Use standard MOVE-ARGUMENT + coercion to move an untagged number to a
  318. ;;; descriptor passing location.
  319. ;;;
  320. (define-move-vop move-argument :move-argument
  321.   (signed-reg unsigned-reg) (any-reg descriptor-reg))
  322.